package com.ctl.szmd.szmd.feature_wm.data.repository

import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import com.blankj.utilcode.util.LogUtils
import com.ctl.lib_common.utils.http.MyResult
import com.ctl.lib_common.utils.livebus.LiveBus
import com.ctl.szmd.szmd.feature_wm.Constants
import com.ctl.szmd.szmd.feature_wm.data.api.WmService
import com.ctl.szmd.szmd.feature_wm.data.bean.FulianSubOrgInfoForListForApiList
import com.ctl.szmd.szmd.feature_wm.data.bean.WmDataBean
import com.ctl.szmd.szmd.feature_wm.data.mapper.wm.ListCommonInfoForApiList2WmDataListModel
import com.ctl.szmd.szmd.feature_wm.data.mapper.wm.WmDataBean2WmDataModel
import com.ctl.szmd.szmd.feature_wm.data.model.WmDataListModel
import com.ctl.szmd.szmd.feature_wm.data.model.WmDataModel
import com.ctl.szmd.szmd.feature_wm.data.repository.pagingsource.*
import com.ctl.szmd.szmd.utils.DownloadUtils
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import okhttp3.ResponseBody
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response

/**
 * created by : chentl
 * Date: 2020/07/23
 */
class WmRepositoryImpl(
    val api: WmService,
    private val pageConfig: PagingConfig
) :
    WmRepository {

    override fun downloadFile(url: String, name: String) {
        val call = api.downloadFile(url)
        call.enqueue(object : Callback<ResponseBody?> {
            override fun onFailure(call: Call<ResponseBody?>, t: Throwable) {
                LogUtils.i("下载失败")
            }

            override fun onResponse(call: Call<ResponseBody?>, response: Response<ResponseBody?>) {
                if (response.isSuccessful) {
                    LogUtils.i(response)
                    val file = DownloadUtils().writeResponseBodyToDisk(response.body(), name)
                    if (file != null) {
                        LogUtils.i("下载成功${file.absolutePath}")
                        LiveBus.get(Constants.LIVE_BUS_FILE_DOWNLOAD_FINISH_OPEN).post(file)
                    } else {
                        LogUtils.i("文件不存在")
                    }
                } else {
                    LogUtils.i("服务器返回错误")
                }
            }
        })
    }

    @ExperimentalCoroutinesApi
    override suspend fun getLoginInfo(map: MutableMap<String, Any>): Flow<MyResult<WmDataModel>> {
        return flow {
            try {
                val info = api.loginInfo(map)
                val result = WmDataBean2WmDataModel().map(info)
                if (result != null) {
                    emit(MyResult.Success(result))
                }
            } catch (e: Exception) {
                emit(MyResult.Failure(e.cause))
            }
        }
//            .flowOn(Dispatchers.IO) // 通过 flowOn 切换到 io 线程
    }

    @ExperimentalCoroutinesApi
    override suspend fun getInfoFacePartyListData(): Flow<PagingData<WmDataListModel>> {
        return Pager(config = pageConfig) {
            InfoFacePartyListPagingSource(api)
        }.flow
    }

    override fun getHeadlineListData(): Flow<PagingData<WmDataListModel>> {
        return Pager(
            config = pageConfig
//            remoteMediator = RemoteMediator()
        ) {
            HeadlinesPagingSource(api)
        }.flow
    }

    override fun getBasicStyleList(): Flow<PagingData<WmDataListModel>> {
        return Pager(
            config = pageConfig
//            remoteMediator = RemoteMediator()
        ) {
            BasicStylePagingSource(api)
        }.flow
    }

    override fun getPettyLoanList(): Flow<PagingData<WmDataListModel>> {
        return Pager(
            config = pageConfig
//            remoteMediator = RemoteMediator()
        ) {
            PettyLoanPagingSource(api)
        }.flow
    }

    override suspend fun getInfoWomenHeadlineListData(): Flow<List<WmDataListModel>> {
        return flow {
            try {
                val info = api.infoWomenHeadlineListData(1, 4)
                val result =
                    ListCommonInfoForApiList2WmDataListModel().map(info.CommonInfoForApiList)
                if (result != null && result.isNotEmpty()) {
                    emit(result)
                }

            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    override suspend fun getInfoVisitCountStatistics(visitTypeNum: Int, infoId: String) {
        doWithTry {
            api.infoVisitCountStatistics(visitTypeNum, infoId)
        }
    }

    override suspend fun getInfoWebViewAttachmentList(
        path: String,
        map: MutableMap<String, String>
    ): Flow<MyResult<WmDataModel>> {
        return flow {
            try {
                val result = api.infoWebViewAttachmentList(path, map)
                val data = WmDataBean2WmDataModel().map(result)
                if (data != null) {
                    emit(MyResult.Success(data))
                }

            } catch (e: Exception) {
                emit(MyResult.Failure(e.cause))
            }
        }
    }

    override suspend fun getBasicStyleListData(
        currentPage: Int,
        pageSize: Int
    ): Flow<List<WmDataListModel>> {
        return flow {
            try {
                val info = api.infoBasicStyleList(currentPage, pageSize)
                val result =
                    ListCommonInfoForApiList2WmDataListModel().map(info.CommonInfoForApiList)
                if (result != null && result.isNotEmpty()) {
                    emit(result)
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    override fun getFulianAppIndexIntro(): Flow<WmDataModel> {
        return flow {
            doWithTry {
                val info = api.fulianAppIndexIntro("All")
                val data = WmDataBean2WmDataModel().map(info)
                if (data?.fulianAppIndexIntro != null) {
                    emit(data)
                }
            }
        }
    }

    override fun getFulianAppIndexSubOrgContentInfoList(dep_id: String?): Flow<PagingData<FulianSubOrgInfoForListForApiList>> {
        return Pager(
            config = pageConfig
        ) {
            SubOrgInfoPagingSource(api, dep_id)
        }.flow
    }

    override suspend fun getFulianMyCenterMyInfo(): Flow<WmDataBean> {
        return flow {
            doWithTry {
                val result = api.fulianMyCenterMyInfo()
                emit(result)
            }
        }
    }
}

inline fun <T, W> T.doWithTry(block: (T) -> W) {
    try {
        block(this)
    } catch (e: Throwable) {
        e.printStackTrace()
        LogUtils.i(e.message)
    }
}